package exebuilder.command;

import exebuilder.ui.MessageBox;
import javafx.application.Platform;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.codehaus.plexus.util.cli.CommandLineException;
import org.codehaus.plexus.util.cli.Commandline;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

public class CommandUtils {

  private static final Logger logger = LogManager.getLogger();

  private static void createArguments(Commandline command, List<String> arguments) {
    for (String argument : arguments) {
      command.createArg().setValue(argument.trim());
    }
  }

  public static String execute(File workingDirectory, String executable, ArrayList<String> arguments) throws Exception {
    StringBuilder outputBuffer = new StringBuilder();
    StringBuilder errorBuffer = new StringBuilder();
    try {
      Commandline command = new Commandline();
      command.setWorkingDirectory(workingDirectory);
      command.setExecutable(executable);
      if (arguments != null) {
        createArguments(command, arguments);
      }
      logger.debug("Executing command: " + StringUtils.join(command.getCommandline(), " "));
      Process process = command.execute();
      BufferedReader output = new BufferedReader(new InputStreamReader(process.getInputStream(), "gbk"));
      BufferedReader error = new BufferedReader(new InputStreamReader(process.getErrorStream(), "gbk"));

      while (process.isAlive()) {
        if (output.ready()) {
          outputBuffer.append(output.readLine()).append("\n");
        }
        if (error.ready()) {
          errorBuffer.append(error.readLine()).append("\n");
        }
      }
      output.close();
      error.close();
    } catch (IOException | CommandLineException e) {
      Platform.runLater(() -> MessageBox.error(e.getMessage()));
      throw new Exception(e.getMessage(), e);
    }
    return outputBuffer.append(errorBuffer).toString();
  }

}
